﻿package com.sparrow.utils;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.URL;
import java.util.Comparator;
import com.sparrow.constant.COMMON;
import com.sparrow.constant.FILE;
import com.sparrow.core.Log;

public class FileUtil {

	private static FileUtil fileUtil = new FileUtil();

	private FileUtil() {
	}

	public static FileUtil getInstance() {
		return fileUtil;
	}

	public String readFileContent(String fileName) {
		return readFileContent(fileName, null);
	}

	/**
	 * 以行为单位读取文件，常用于读面向行的格式化文件
	 */
	public String readFileContent(String fileName, String charset) {
		if (StringUtil.isNullOrEmpty(charset)) {
			charset = "UTF-8";
		}
		File file = new File(fileName);
		BufferedReader reader = null;
		StringBuffer sb = new StringBuffer();
		try {
			reader = new BufferedReader(new InputStreamReader(
					new FileInputStream(file), charset));
			String tempString = null;
			while ((tempString = reader.readLine()) != null) {
				sb.append(tempString);
				sb.append(COMMON.ENTER_TEXT);
			}
			reader.close();
		} catch (IOException e) {
			Log.getInstance().error(e);
		} finally {
			if (reader != null) {
				try {
					reader.close();
				} catch (IOException e1) {
				}
			}
		}
		return sb.toString();
	}

	public boolean writeFile(String filePath, String s) {
		String charset = "UTF-8";
		return writeFile(filePath, s, charset);
	}

	public boolean writeFile(String filePath, String s, String charset) {
		OutputStreamWriter osw = null;
		try {
			osw = new OutputStreamWriter(new FileOutputStream(filePath),
					charset);
			osw.write(s, 0, s.length());
			osw.flush();
			return true;
		} catch (Exception e) {
			Log.getInstance().error(e);
			return false;
		} finally {
			if (osw != null) {
				try {
					osw.close();
				} catch (IOException e) {
				}
			}
		}
	}

	/**
	 * 文件复制
	 * 
	 * @author zhanglizhi
	 * @date 2011-12-24
	 * @version 1.0
	 * @param descFilePath
	 * @param srcFilePath
	 */
	public void copy(String srcFilePath, String descFilePath) {
		InputStream is = null;
		FileOutputStream fos = null;
		try {
			// 目录图所在路径
			String descDirectoryPath = descFilePath.substring(0,
					descFilePath.lastIndexOf('/') + 1);
			// 判断并创建原图路径
			File descDirectory = new File(descDirectoryPath);
			if (!descDirectory.exists()) {
				descDirectory.mkdirs();
			}
			// 目标图文件对象
			File descFile = new File(descFilePath);
			is = new FileInputStream(srcFilePath);
			fos = new FileOutputStream(descFile);
			byte[] buffer = new byte[1024];
			while (true) {
				int readedSize = is.read(buffer);
				if (readedSize == -1) {
					break;
				}
				fos.write(buffer, 0, readedSize);
			}

		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (is != null) {
				try {
					is.close();
				} catch (IOException e) {
				}
			}
			if (fos != null) {
				try {
					fos.close();
				} catch (IOException e) {
				}
			}
		}
	}

	public String search(String path, String keyword, int bufferSize,
			Comparator<String> compare, int minSkip) {
		File file = new File(path);
		BufferedReader reader = null;
		try {
			reader = new BufferedReader(new InputStreamReader(
					new FileInputStream(file), "utf-8"), bufferSize);
			String tempString = null;
			reader.mark(bufferSize);
			int skip = bufferSize / 2;
			reader.skip(skip);
			reader.readLine();
			boolean isSkip = true;
			int count = 0;
			String lastWord = COMMON.EMPTY;
			while ((tempString = reader.readLine()) != null) {
				count++;
				if (compare.compare(tempString, keyword) == 0) {
					System.out.println(count);
					return tempString;
				} else if (tempString.equals(lastWord)) {
					System.out.println(count);
					return COMMON.EMPTY;
				}
				// 是否需要skip
				if (isSkip) {
					System.out.println("skip" + count);
					// 往外跳
					if (compare.compare(tempString, keyword) < 0) {
						// 先 做标记
						reader.mark(bufferSize);
						// 如果不足标准skip 说明已经定位到，跳跃浮度减半
						if (skip < bufferSize / 2) {
							skip /= 2;
						} else {
							// 跳出文本范围 则减半
							while (reader.skip(skip) < skip) {
								skip /= 2;
								reader.reset();
							}
						}
						reader.readLine();
						// 向里跳
					} else {
						reader.reset();
						skip /= 2;
						if (skip <= minSkip) {
							isSkip = false;
							lastWord = tempString;
						} else {
							reader.skip(skip);
							reader.readLine();
						}
					}
				}
			}
			reader.close();
			return COMMON.EMPTY;
		} catch (IOException e) {
			Log.getInstance().error(e);
			return COMMON.EMPTY;
		} finally {
			if (reader != null) {
				try {
					reader.close();
				} catch (IOException e1) {
				}
			}
		}
	}

	/**
	 * 根据单位为KB的长度获取文件长度（可变单位为MB GB）
	 * 
	 * @author zhanglizhi
	 * @date Apr 9, 2011
	 * @version 1.0
	 * @param length
	 *            单位是KB
	 * @return
	 */
	public String getFileLength(double length) {
		if (length < 1) {// 获取其整数部分
			return String.valueOf(Math.ceil(length * 1024)) + "B";
		} else if (length >= 1 && length < 1024) {// 不小于这个数的最小整数
			return String.valueOf(Math.ceil(length)) + "KB";
		} else if (length >= 1024 && length < Math.pow(1024, 2)) {// 四舍五入保留两位小数
			return Math.ceil(length / 1024 * 100) / 100 + "MB";
		} else {// 四舍五入保留两位小数
			return Math.ceil(length / 1024 / 1024 * 100) / 100 + "GB";
		}
	}

	/**
	 * 获取当前classes文件夹../WebRoot/WEB-INF/classes/
	 * 
	 * @author zhanglizhi
	 * @date May 29, 2011
	 * @version 1.0
	 * @return
	 */
	public String getClassesPhysicPath() {
		URL url = Thread.currentThread().getContextClassLoader()
				.getResource("");
		if (url != null) {
			return url.getPath().replace("%20", " ");

		} else {
			String path = this.getClass().getProtectionDomain().getCodeSource()
					.getLocation().getPath();
			return path.substring(0, path.lastIndexOf('/'));
		}
	}

	/**
	 * 获取当WebRoot文件夹
	 * 
	 * @author zhanglizhi
	 * @date May 29, 2011
	 * @version 1.0
	 * @return
	 */
	public String getWebRootPhysicPath() {
		String path = getClassesPhysicPath();
		return path.substring(0, path.indexOf("WEB-INF"));
	}

	/**
	 * 获取当WEB-INF文件夹
	 * 
	 * @author zhanglizhi
	 * @date May 29, 2011
	 * @version 1.0
	 * @return
	 */
	public String getWebInfPhysicPath() {
		String path = getClassesPhysicPath();
		return path.substring(0, path.indexOf("classes"));
	}

	public String getExtension(String fileUrl) {
		String extension = fileUrl.substring(fileUrl.lastIndexOf('.'))
				.toLowerCase();
		String[] imgageExtension = Config.getValueInCache(FILE.IMAGE_EXTENSION)
				.split("\\|");
		// jpeg 或者是其他格式都转换成jpg
		if (extension.toLowerCase().equals(".jpeg")
				|| !StringUtil.isInArray(imgageExtension, extension)) {
			extension = ".jpg";
		}
		return extension;
	}

	/**
	 * 获取文件名 不包含扩展名
	 * 
	 * @author zhanglizhi
	 * @date 2012-9-22
	 * @version 1.0
	 * @param imageUrl
	 * @return
	 */
	public String getFileName(String imageUrl) {
		// 获取客户端文件名 http://img.zhuaququ.com/0/0.100.jpg?date=new date()
		int fileNameStartIndex = imageUrl.lastIndexOf('/') + 1;
		int fileNameEndIndex = imageUrl.lastIndexOf('.');
		String fileName = imageUrl.substring(fileNameStartIndex,
				fileNameEndIndex);
		return fileName;
	}

	/**
	 * 通过一数字ID获取文件打散路径
	 * 
	 * @author zhanglizhi
	 * @date 2012-9-9
	 * @version 1.0
	 * @param id
	 * @param extension
	 * @param isWebPath
	 * @param size
	 * @return
	 */
	public String getBreakUpPath(int id, String extension, boolean isWebPath,
			String size) {
		boolean isImage = this.isImage(extension);
		int remaining = id % 10;
		int remaining1 = id % 1000;
		int div = id / 1000;
		int remaining2 = div % 1000;
		String path = "";
		if (isImage) {
			if (isWebPath) {
				path = Config.getValueInCache(FILE.PATH.IMG_URL)
						+ "/%2$s/%3$s/%4$s/%5$s%6$s";
			} else {
				path = Config.getValueInCache(FILE.PATH.IMG_UNC)
						+ "/%2$s/%3$s/%4$s/%5$s%6$s";
			}
			return String.format(path, remaining, size, remaining2, remaining1,
					id, extension);
		} else {
			path = Config.getValueInCache(FILE.PATH.FILE_UNC)
					+ "/%1$s/%2$s/%3$s%4$s";
			return String.format(path, remaining2, remaining1, id, extension);
		}
	}

	public boolean isImage(String extension) {
		return StringUtil.isInArray(Config
				.getValueInCache(FILE.IMAGE_EXTENSION).split("\\|"), extension);
	}

	/**
	 * 根据站内附件url获取物理路径
	 * 
	 * @param filePath
	 * @param size
	 * @return
	 */
	public String getPhysicalPath(String filePath, String size) {
		String fileId = this.getFileName(filePath);
		String extension = this.getExtension(filePath);
		return this.getBreakUpPath(Integer.valueOf(fileId), extension, false,
				size);
	}

	public void delete(String path, long beforeMillis) {
		File file = new File(path);
		File[] files = file.listFiles();
		for (File f : files) {
			if (f.isDirectory() && !f.isHidden()) {
				delete(f.getPath(), beforeMillis);
			} else {
				if (f.lastModified() < beforeMillis) {
					f.delete();
				}
			}
		}
	}
}